﻿using System;
using System.Windows;
using System.Windows.Media;

using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Modularity;
using Microsoft.Practices.Composite.Regions;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Composite.Presentation.Events;

using Matchingo.Common.Constants;
using Matchingo.Common.Types.Enumerations;
using Matchingo.Common.Types.Events;
using Matchingo.Common.Types.EventArguments;
using Matchingo.Common.Types.Interfaces;

namespace Matchingo.Modules.ParticleRenderModule
{
    public class ParticleEffectsViewModel : DependencyObject, IModule
	{
		#region ========== Public Properties ==========

		public double SoundVolume
		{
			get { return SettingsProvider.GameSettings.SoundVolume; }
		}

		#endregion

		#region ========== Private Properties ==========

		private IParticleEffectsView View;

        private readonly IUnityContainer Container;
        private readonly IEventAggregator EventAggregator;
        private readonly IRegionManager RegionManager;
        private readonly IParticleControlFactory ParticleFactory;
		private readonly IGameSettingsProvider SettingsProvider;

        #endregion

        #region ========== Constructor ==========

        public ParticleEffectsViewModel(IUnityContainer container,
            IEventAggregator eventAggregator, 
            IRegionManager regionManager,
            IGameSettingsProvider settingsProvider,
            IParticleControlFactory particleFactory)
        {
            Container = container;
            RegionManager = regionManager;
			SettingsProvider = settingsProvider;
            ParticleFactory = particleFactory;
            EventAggregator = eventAggregator;
        }

        #endregion

        #region ========== Public Methods ==========

        public void Initialize()
        {
            View = Container.Resolve<IParticleEffectsView>();
            View.Initialize(this);

            IRegion region = RegionManager.Regions[CommonConstants.SHELL_REGION_Particles]; 
            region.Add(View);

            EventAggregator.GetEvent<ParticleFireRequestEvent>().Subscribe(ParticleProviderParticlesFired, ThreadOption.UIThread, true);
        }
      
        public UIElement GetParticleInstance(ParticleTypeEnumeration.ParticleType particleType, int matchComboCount)
        {
            UIElement e = ParticleFactory.GetParticleInstance(particleType, matchComboCount);

            e.RenderTransform = new TranslateTransform();
            e.RenderTransformOrigin = new Point(0.5, 0.5);

            return e;
        }

        #endregion

        #region ========== Event Handlers ==========

        private void ParticleProviderParticlesFired(FireParticlesEventArgs e)
        {
            FireParticles(e.CenterX, e.CenterY, e.ParticleType, e.MatchComboCount, e.PlaySounds);
        }

        private void FireParticles(double centerX, double centerY, ParticleTypeEnumeration.ParticleType particleType,
            int matchComboCount, bool playSounds)
        {
            int particleCount;

            switch (particleType)
            {
                case ParticleTypeEnumeration.ParticleType.FlipCelebration:
                    particleCount = CommonConstants.PARTICLE_COUNT_CARD_FLIPPED;
                    break;
                case ParticleTypeEnumeration.ParticleType.MatchCelebration:
                    particleCount = CommonConstants.PARTICLE_COUNT_CARDS_MATCHED;
                    break;
                default:
                    throw new ArgumentException("ParticleModule.FireParticles() - unknown ParticleTypeEnumeration requested");
            }

            View.FireParticles(centerX, centerY, particleType, particleCount, matchComboCount, playSounds);
        }

        #endregion
    }
}
